package phototour3.client;



import java.util.LinkedList;
import java.util.List;

import com.gargoylesoftware.htmlunit.javascript.host.Text;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.InfoWindowContent.InfoWindowTab;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.maps.client.overlay.Polyline;
import com.google.gwt.maps.client.overlay.PolylineOptions;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;





public class Phototour3 implements EntryPoint {

	private VerticalPanel mainPanel = new VerticalPanel();
	private HorizontalPanel addPanel = new HorizontalPanel();
//	private TextBox lat1 = new TextBox();
//	private TextBox long1 = new TextBox();
//	private TextBox lat2 = new TextBox();
//	private TextBox long2 = new TextBox();
	private Button submit = new Button("Buscar");
	private HorizontalPanel hPanel2 = new HorizontalPanel();
	private VerticalPanel vPanel = new VerticalPanel();
	private Integer numberOfPoints;	//lo necesito para ir rellenando los puntos a unir TODO
	private LatLng[] mapsPoints=new LatLng[102];
	
	private HorizontalPanel check = new HorizontalPanel();
	private static String checkControl="";
	private DialogBox db= new DialogBox();
	//private static final String JSON_URL = "http://www.panoramio.com/map/get_panoramas.php?order=popularity&set=full&from=0&to=10&";
	private MapWidget map;
	
	private String actualPhotoTitle;
	
	private Algorithm algorithm;
	
	public String photoTite(){
		return actualPhotoTitle;
	}
	
	public static void setCheckControl(String s){
		checkControl+=s;
	}
	
	public void onModuleLoad() {
		
//		
		LatLng mapCenter = LatLng.newInstance( 37.384439,  -5.945917);
	    // Open a map centered on Cawker City, KS USA
//		
		map = new MapWidget(mapCenter, 11);
	    map.setSize("900px", "400px");
//	    
	    // Add some controls for the zoom level
	    map.addControl(new LargeMapControl());
	    
	    // Add a marker
	    map.addOverlay(new Marker(mapCenter));

	    // Add an info window to highlight a point of interest
	    map.getInfoWindow().open(map.getCenter(), 
	        new InfoWindowContent("¡¡This is my city!!"));
	    
	    
	    
	    // Add the map to the HTML host page
	    RootPanel.get("map").add(map);
		
//		addPanel.add(new Label("Long1(minx)"));
//		addPanel.add(long1);
//		addPanel.add(new Label("Lat1(miny)"));
//		addPanel.add(lat1);
//		hPanel2.add(new Label("Long2(maxx)"));
//		hPanel2.add(long2);
//		hPanel2.add(new Label("Lat2(maxy)"));
//		hPanel2.add(lat2);
		
		vPanel.add(submit);
		mainPanel.add(addPanel);
		mainPanel.add(hPanel2);
		mainPanel.add(vPanel);

		// Associate the main panel with HTML
		
		RootPanel.get("phototour").add(mainPanel);
		submit.addClickHandler(new ClickHandlerImpl());
		
		db.setText(checkControl);
		db.setTitle("funcionamiento del código y procesado");
		db.setWidth("70em");
		RootPanel.get("dialogPanel").add(db);
		
		
	}

	private class ClickHandlerImpl implements ClickHandler {

		
		public void onClick(ClickEvent event) {
			
			
			
			//ésta línea de código la pongo para que cuando el usuario vuelva a pulsar buscar
			//sin recargar la pág le salga el mapa sin los marcadores de su anterior busqueda
			map.clearOverlays();
			
			numberOfPoints=0;// TODO
			
			
			Double latitudMax=map.getBounds().getNorthEast().getLatitude();
		    Double longitudMax=map.getBounds().getNorthEast().getLongitude();
		    Double latitudMin=map.getBounds().getSouthWest().getLatitude();
		    Double longitudMin=map.getBounds().getSouthWest().getLongitude();
		    
		    //If phototour is running on appEngine the url is:
			// "http://nombre del proyecto en el servidor/clase del servidor
		    //in this case:
		    
//			String url="http://phototour3.appspot.com/PhotoRequest?lat1="	
//			+ latitudMin + "&lat2=" + latitudMax
//			+ "&long1=" + longitudMin + "&long2="	
//			+ longitudMax;
			
		    
		  //If phototour is running on the local server, the url is:
			String url = "http://127.0.0.1:8888/PhotoRequest?lat1="	
						+ latitudMin + "&lat2=" + latitudMax
						+ "&long1=" + longitudMin + "&long2="	
						+ longitudMax;
				
			//añado un panel de dialogo para la url
			checkControl=url;
			DialogBox d1=new DialogBox();
			d1.setWidth("70em");
			d1.setText(checkControl);
			db.add(d1);
			
			
			RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL
					.encode(url));

			try {
				Request r= builder.sendRequest(null,
						new RequestCallback() {
							public void onError(Request request,
									Throwable exception) {
								// Couldn't connect to server (could be timeout,
								// SOP violation, etc.)
							}

							public void onResponseReceived(Request request,
									Response response) {
								if (200 == response.getStatusCode()) {
									// Process the response in response.getText()
									
									checkControl="request ok";
									db.setText(checkControl);
									//Window.alert("OK4");
									checkControl+=response.getText();
									//Window.alert(response.getText());
									// Method to process JSON
									jsonProcess(response.getText());
									db.setText(checkControl);
									
									
								} else {
									checkControl+="bad request";
									db.setText(checkControl);
									//Window.alert("BAD4:"
									//		+ response.getStatusCode());
								}
							}
						});
			} catch (RequestException e) {
				// Couldn't connect to server
				
				
			}

		}

	}
	public void jsonProcess(String text){
		
		// Index of ("{")
		int index=text.indexOf("{");	
		
		//String built
		
		String substringJSON=text.substring(index);
		
		//para probar
		System.out.println("\n"+substringJSON);
		
		checkControl+=substringJSON;
		db.setText(checkControl);
		//Window.alert(substringJSON);
		
		JSONValue jsonValue=JSONParser.parse(substringJSON);  // Parser to JSON
		JSONObject jsonObject=jsonValue.isObject();			  //Parser to Object
		JSONValue takePhotos=jsonObject.get("photos");	//JSONValue
		JSONArray jsonArray=takePhotos.isArray();	// Parser to JSONArray
		
		if(jsonArray!=null){
			
//			PhotoNumber			
//			Integer photoNumber=Integer.parseInt((jsonObject.get("count")).toString());
//			Window.alert(photoNumber.toString());
//			
			
//			Number of photos in the array
			Integer photoNumber2=jsonArray.size();
			//Window.alert(photoNumber2.toString());
			
			checkControl+="number of photos"+ photoNumber2.toString();
			db.setText(checkControl);
//			VerticalPanel photoPannel=new VerticalPanel();
//			mainPanel.add(photoPannel);
			
			
			
			List<Photo> photoPoints=new LinkedList<Photo>();
			for(int i=0;i<photoNumber2;i++){
				JSONValue photoValue=jsonArray.get(i);
				JSONObject photoi=photoValue.isObject();
				
				photoPoints.add(createPhotosFromJSON(photoi));
				
			}
			//Window.alert("I found the points");
			checkControl+="Puntos encontrados";
			db.setText(checkControl);
			
			//We choose the algorithm
			
			algorithm=new AlgorithmOne();
			List<Area> interestingAreas=algorithm.interestingAreas(photoPoints);
			//Window.alert("The interesting areas are:"+interestingAreas.toString());
			checkControl+="The interesting areas are:"+interestingAreas.toString();
			db.setText(checkControl);
			for(int i=0;i<interestingAreas.size();i++){
				HorizontalPanel areaAndImage=new HorizontalPanel();
				
				//Name of the Area (popularity)
				Label areaName=new Label("Area"+i);
				
				Photo photo=interestingAreas.get(i).getTheMostPopularPhoto();
				
				// Image creation
				
				String photoUrl=photo.getUrl_ubication();
				Image asociatedImage=new Image(photoUrl);
				
				
				// Name
				String photoN=photo.getPhotoName();
				Label photoName=new Label(photoN);
				
				//Representation map
				
				Double latitudeOfTheMainPhoto=photo.getLatitude();
				Double longitudeOfTheMainPhoto=photo.getLongitude();
				representationMap(latitudeOfTheMainPhoto,longitudeOfTheMainPhoto,photoUrl,i);
				

				
				// HiperLink Creation
				
				String photoHyperlink=photo.getHyperlink();
				Hyperlink hyperlink=new Hyperlink(photoHyperlink,"");
				
				areaAndImage.add(areaName);
				areaAndImage.add(asociatedImage);
				areaAndImage.add(photoName);

				areaAndImage.add(hyperlink);
				mainPanel.add(areaAndImage);
			}
	
		}else
			throw new JSONException();
		

		//TODO
//		options.setGeodesic(true);
		LatLng [] pepe={LatLng.newInstance(-6.0, 37.0),LatLng.newInstance(-5.5, 37.002)};
		Polyline polyline=new Polyline(pepe, "#FF00FF", 1, 1.0,
				PolylineOptions.newInstance(true));
        
        map.addOverlay(polyline);
        Window.alert("tenemos"+mapsPoints.length+"puntos a representar");
	}
	
	
	public Photo createPhotosFromJSON(JSONObject photoi){
		
				// Latitude Parameter
		
				JSONValue latitudValue=photoi.get("latitude");
				JSONNumber jsonLat=latitudValue.isNumber();
				Double latitude=jsonLat.doubleValue();
				
				//Longitude Parameter
				
				JSONValue longitudeValue=photoi.get("longitude");
				JSONNumber jsonLong=longitudeValue.isNumber();
				Double longitude=jsonLong.doubleValue();
				
				//Photo name
				
				JSONValue valueName=photoi.get("photo_title");
				JSONString jsonName=valueName.isString();
				String name=jsonName.stringValue();
				actualPhotoTitle=name;
				
				//Photo URL
				
				JSONValue valueUrl=photoi.get("photo_file_url");
				JSONString jsonUrl=valueUrl.isString();
				String url=jsonUrl.stringValue();
				
				Photo photoPointi=new Photo(latitude,longitude,name,url);
				return photoPointi;
	}


	/**
	 * Getter of the property <tt>algorithmsStrategy</tt>
	 * @return  Returns the algorithmsStrategy.
	 * @uml.property  name="algorithmsStrategy"
	 */
	public Algorithm getAlgorithm() {
		return algorithm;
	}


	/**
	 * Setter of the property <tt>algorithmsStrategy</tt>
	 * @param algorithmsStrategy  The algorithmsStrategy to set.
	 * @uml.property  name="algorithmsStrategy"
	 */
	public void setAlgorithmsStrategy(Algorithm algorithmsStrategy) {
		this.algorithm = algorithmsStrategy;
	}
	public void representationMap(Double latitude,Double longitude,String imageUrl,Integer numeroArea){//TODO
		
		
		//la latitud y la longitud que queremos representar son las de cada una de las fotos
		//principales de las areas de interés halladas y devueltas por pantalla
		//de modo que este metodo tiene que llamarse dentro del que se procesan cada una de
		//las areas(y se muestran sus fotos)
		Icon icon=Icon.newInstance("http://labs.google.com/ridefinder/images/mm_20_red.png");
		MarkerOptions markerOption=MarkerOptions.newInstance(icon);
		
		//necesito meter dentro de el marcador el titulo de la imagen porque en el manejador 
		//no puedo usar parametros,solo el contenido de los atributos del marcador(que es el sendler)
		markerOption.setTitle(imageUrl);
		LatLng ubicacionPhotoi=LatLng.newInstance(latitude, longitude);
		Marker m=new Marker(ubicacionPhotoi,markerOption);
		//InfoWindowContent iw=new InfoWindowContent(new Image("http://labs.google.com/ridefinder/images/mm_20_red.png",2,2,2,2));
		
		
		m.addMarkerClickHandler(new MarkerClickHandler(){
			public void onClick(MarkerClickEvent event) {
				Image i=new Image(event.getSender().getTitle());
				i.setSize("20em", "20em");
				InfoWindowTab i1=new InfoWindowTab("imagen", i);
				Hyperlink hyp=new Hyperlink(event.getSender().getTitle(),true,"");
				InfoWindowTab i2=new InfoWindowTab("Información:",hyp);
				//creo pestañas con la imagen principal y con lo que sea que quiera añadir tambien
				InfoWindowTab [] it={i1,i2};
				
				//asocio a la ventana la pestaña, y digo que la 0 será la pcipal
				InfoWindowContent iwc=new InfoWindowContent(it,0);
				
				
				map.getInfoWindow().open(event.getSender().getLatLng(),iwc);
				//una vez pulsado le cambio el color al marcador
				event.getSender().setImage("phototour3/gwt/standard/images/mm_20_purple.png");	
			}
			
		});
		map.addOverlay(m);
		
		//map.addOverlay(overlayLineas);
		
		mapsPoints[numeroArea]=ubicacionPhotoi;	//voy rellenando el array
//		PolylineOptions options=PolylineOptions.newInstance();
//		options.setGeodesic(true);
//        
//        Polyline polyline=new Polyline(mapsPoints, "#00FFFF", 2, 4,
//        	       options);
//        
//        map.addOverlay(polyline);
		
		
		
	}	
		
}